/*
 * stm32_uart.c
 *
 *  Created on: 2022年4月14日
 *      Author: chain
 */





#include "main.h"
#include "stm32_uart.h"
#include "string.h"
#include "log.h"
#include "My_RB_FIFO.h"
#include "stm32_uart_config.h"

#if FREERTOS_USE
#include "FreeRTOS.h"
#include "semphr.h"
#include "stream_buffer.h"
#endif

SemaphoreHandle_t uart1_sem_handle;
SemaphoreHandle_t uart2_sem_handle;
SemaphoreHandle_t uart3_sem_handle;
SemaphoreHandle_t uart4_sem_handle;
SemaphoreHandle_t uart5_sem_handle;
SemaphoreHandle_t uart6_sem_handle;
SemaphoreHandle_t lpuart1_sem_handle;


//
StreamBufferHandle_t uart1_stream_buff;
StreamBufferHandle_t uart2_stream_buff;
StreamBufferHandle_t uart3_stream_buff;
StreamBufferHandle_t uart4_stream_buff;
StreamBufferHandle_t uart5_stream_buff;
StreamBufferHandle_t uart6_stream_buff;
StreamBufferHandle_t lpuart1_stream_buff;



#define LOG_OUT_RX_LEN_INFO     0


//StreamBufferHandle_t uart4_stream_buff;



#if UART1_EN
extern UART_HandleTypeDef huart1;
uint8_t uart1_dma_rx_buff[UART1_DMA_RX_BUF_LEN];
uint8_t uart1_dma_tx_buff[UART1_DMA_TX_BUF_LEN];
#endif      /* UART1_EN */

#if UART2_EN
extern UART_HandleTypeDef huart2;
uint8_t uart2_dma_rx_buff[UART2_DMA_RX_BUF_LEN];
uint8_t uart2_dma_tx_buff[UART2_DMA_TX_BUF_LEN];
#endif      /* UART2_EN */

#if UART3_EN
extern UART_HandleTypeDef huart3;
uint8_t uart3_dma_rx_buff[UART3_DMA_RX_BUF_LEN];
uint8_t uart3_dma_tx_buff[UART3_DMA_TX_BUF_LEN];
#endif      /* UART3_EN */

#if UART4_EN
extern UART_HandleTypeDef huart4;
uint8_t uart4_dma_rx_buff[UART4_DMA_RX_BUF_LEN];
uint8_t uart4_dma_tx_buff[UART4_DMA_TX_BUF_LEN];
#endif      /* UART4_EN */

#if UART6_EN
extern UART_HandleTypeDef huart4;
uint8_t uart6_dma_rx_buff[UART6_DMA_RX_BUF_LEN];
uint8_t uart6_dma_tx_buff[UART6_DMA_TX_BUF_LEN];
#endif      /* UART6_EN */


#if LPUART1_EN
extern UART_HandleTypeDef hlpuart1;
uint8_t lpuart1_dma_rx_buff[LPUART1_DMA_RX_BUF_LEN];
uint8_t lpuart1_dma_tx_buff[LPUART1_DMA_TX_BUF_LEN];
#endif      /* LPUART1_EN */

void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
{

}

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;

    __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
#if UART1_EN
    if(huart->Instance == USART1)
    {
        xSemaphoreGiveFromISR(uart1_sem_handle, &xHigherPriorityTaskWoken);
//        LOGW("UART1 TX Cplt.\r\n");
    }
#endif

#if UART2_EN
    if(huart->Instance == USART2)
    {
        xSemaphoreGiveFromISR(uart2_sem_handle, &xHigherPriorityTaskWoken);
//        LOGW("UART2 TX Cplt.\r\n");
    }
#endif


#if UART3_EN
    if(huart->Instance == USART3)
    {
        xSemaphoreGiveFromISR(uart3_sem_handle, &xHigherPriorityTaskWoken);
//        LOGW("UART3 TX Cplt.\r\n");
    }

#endif

#if UART4_EN
    if(huart->Instance == UART4)
    {
        xSemaphoreGiveFromISR(uart4_sem_handle, &xHigherPriorityTaskWoken);
    }
#endif

#if LPUART1_EN
    else if(huart->Instance == LPUART1)
    {
        xSemaphoreGiveFromISR(lpuart1_sem_handle, &xHigherPriorityTaskWoken);
    }
#endif

    portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}

void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
{

}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{

}

void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
    LOGE("HAL_UART_ErrorCallback\r\n");

#if UART1_EN
    if (huart->Instance == USART1)
    {
        LOGE("USART1 ERROR. %d\r\n", huart->ErrorCode);
        // 解锁
        __HAL_UNLOCK(huart);

        // 这段代码就文档说明的内容
        __HAL_UART_CLEAR_FEFLAG(huart);
    }
#endif

#if UART2_EN
    if (huart->Instance == USART2)
    {
        LOGE("USART2 ERROR. %d\r\n", huart->ErrorCode);
    }
#endif

#if UART3_EN
    if (huart->Instance == USART3)
    {
        // 解锁
        __HAL_UNLOCK(huart);

        // 这段代码就文档说明的内容
        __HAL_UART_CLEAR_FEFLAG(huart);
        LOGE("USART3 ERROR. %d\r\n", huart->ErrorCode);
    }
#endif

#if LPUART1_EN

    if (huart->Instance == LPUART1)
    {
        LOGE("LPUART1 ERROR. %d\r\n", huart->ErrorCode);
    }
#endif
}

void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart)
{

}

void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart)
{

}

void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart)
{

}

void stm32_uart_init(void)
{
#if UART1_EN
    uart1_sem_handle = xSemaphoreCreateBinary();
    xSemaphoreGive(uart1_sem_handle);
    uart1_stream_buff = xStreamBufferCreate(UART1_DMA_RX_BUF_LEN, 1);
    HAL_UARTEx_ReceiveToIdle_DMA(&huart1, uart1_dma_rx_buff, UART1_DMA_RX_BUF_LEN);
#endif      /* UART1_EN */


#if UART2_EN
    uart2_sem_handle = xSemaphoreCreateBinary();
    xSemaphoreGive(uart2_sem_handle);
    uart2_stream_buff = xStreamBufferCreate(UART2_DMA_RX_BUF_LEN, 1);
    HAL_UARTEx_ReceiveToIdle_DMA(&huart2, uart2_dma_rx_buff, UART2_DMA_RX_BUF_LEN);
#endif      /* UART2_EN */

#if UART3_EN
    uart3_sem_handle = xSemaphoreCreateBinary();
    xSemaphoreGive(uart3_sem_handle);
    uart3_stream_buff = xStreamBufferCreate(UART3_DMA_RX_BUF_LEN, 1);
    HAL_UARTEx_ReceiveToIdle_DMA(&huart3, uart3_dma_rx_buff, UART3_DMA_RX_BUF_LEN);
#endif      /* UART4_EN */

#if UART4_EN
    uart4_sem_handle = xSemaphoreCreateBinary();
    xSemaphoreGive(uart4_sem_handle);
    uart4_stream_buff = xStreamBufferCreate(UART4_DMA_RX_BUF_LEN, 1);
    HAL_UARTEx_ReceiveToIdle_DMA(&huart4, uart4_dma_rx_buff, UART4_DMA_RX_BUF_LEN);
#endif      /* UART4_EN */


#if UART6_EN
    uart6_sem_handle = xSemaphoreCreateBinary();
    xSemaphoreGive(uart6_sem_handle);
    uart6_stream_buff = xStreamBufferCreate(UART6_DMA_RX_BUF_LEN, 1);
    HAL_UARTEx_ReceiveToIdle_DMA(&huart6, uart6_dma_rx_buff, UART6_DMA_RX_BUF_LEN);
#endif      /* UART4_EN */


#if LPUART1_EN
    lpuart1_sem_handle = xSemaphoreCreateBinary();
    xSemaphoreGive(lpuart1_sem_handle);
    lpuart1_stream_buff = xStreamBufferCreate(LPUART1_DMA_RX_BUF_LEN, 1);
    HAL_UARTEx_ReceiveToIdle_DMA(&hlpuart1, lpuart1_dma_rx_buff, LPUART1_DMA_RX_BUF_LEN);

#endif      /* LPUART1_EN */

}





uint16_t stm32_uart_recv(uint8_t port, uint8_t *p_data, uint16_t len, uint32_t wait_tick)
{
    switch (port)
    {
#if UART1_EN
        case UART1_PORT:
            return xStreamBufferReceive(uart1_stream_buff, p_data, len, wait_tick);
        break;
#endif

#if UART2_EN
        case UART2_PORT:
            return xStreamBufferReceive(uart2_stream_buff, p_data, len, wait_tick);
        break;
#endif

#if UART3_EN
        case UART3_PORT:
            return xStreamBufferReceive(uart3_stream_buff, p_data, len, wait_tick);
        break;
#endif

#if UART4_EN
        case UART4_PORT:
            return xStreamBufferReceive(uart4_stream_buff, p_data, len, wait_tick);
        break;
#endif


#if UART5_EN
        case UART5_PORT:
            return xStreamBufferReceive(uart5_stream_buff, p_data, len, wait_tick);
        break;
#endif


#if UART6_EN
        case UART6_PORT:
            return xStreamBufferReceive(uart6_stream_buff, p_data, len, wait_tick);
        break;
#endif

        case LPUART1_PORT:
            return xStreamBufferReceive(lpuart1_stream_buff, p_data, len, wait_tick);
        break;

        default:

            break;
    }
    return 0;
}

void stm32_uart_send(uint8_t port, uint8_t *p_data, uint16_t len)
{
    switch (port)
    {
        case UART1_PORT:
            xSemaphoreTake(uart1_sem_handle, portMAX_DELAY);
            memcpy(uart1_dma_tx_buff, p_data, len);
            HAL_UART_Transmit_DMA(&huart1, uart1_dma_tx_buff, len);
            break;
#if UART2_EN
        case UART2_PORT:
            xSemaphoreTake(uart2_sem_handle, portMAX_DELAY);
            memcpy(uart2_dma_tx_buff, p_data, len);
            HAL_UART_Transmit_DMA(&huart2, uart2_dma_tx_buff, len);
            break;
#endif

#if UART3_EN
        case UART3_PORT:
            xSemaphoreTake(uart3_sem_handle, portMAX_DELAY);
            memcpy(uart3_dma_tx_buff, p_data, len);
            HAL_UART_Transmit_DMA(&huart3, uart3_dma_tx_buff, len);
            break;
#endif

#if UART4_EN
        case UART4_PORT:
            xSemaphoreTake(uart4_sem_handle, portMAX_DELAY);
            memcpy(uart4_dma_tx_buff, p_data, len);
            HAL_UART_Transmit_DMA(&huart4, uart4_dma_tx_buff, len);
            break;
#endif

#if LPUART1_EN
        case LPUART1_PORT:
            xSemaphoreTake(lpuart1_sem_handle, portMAX_DELAY);
            memcpy(lpuart1_dma_tx_buff, p_data, len);
            HAL_UART_Transmit_DMA(&hlpuart1, lpuart1_dma_tx_buff, len);
            break;
#endif
        default:
            //错误
            break;
    }
}

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
#if UART1_EN
    if (huart->Instance == USART1 && huart->RxState == HAL_UART_STATE_READY)
    {
        xStreamBufferSendFromISR(uart1_stream_buff, uart1_dma_rx_buff, Size, &xHigherPriorityTaskWoken);
        HAL_UARTEx_ReceiveToIdle_DMA(&huart1, uart1_dma_rx_buff, UART1_DMA_RX_BUF_LEN);
#if LOG_OUT_RX_LEN_INFO
        LOGI("USART1 RX %d byte.\r\n", Size);
#endif
    }
#endif

#if UART2_EN
    if (huart->Instance == USART2 && huart->RxState == HAL_UART_STATE_READY)
    {
        xStreamBufferSendFromISR(uart2_stream_buff, uart2_dma_rx_buff, Size, &xHigherPriorityTaskWoken);
        HAL_UARTEx_ReceiveToIdle_DMA(&huart2, uart2_dma_rx_buff, UART2_DMA_RX_BUF_LEN);
//        LOGI("USART2 RX %d byte.\r\n", Size);
    }
#endif

#if UART3_EN
    if (huart->Instance == USART3 && huart->RxState == HAL_UART_STATE_READY)
    {
        xStreamBufferSendFromISR(uart3_stream_buff, uart3_dma_rx_buff, Size, &xHigherPriorityTaskWoken);
        HAL_UARTEx_ReceiveToIdle_DMA(&huart3, uart3_dma_rx_buff, UART3_DMA_RX_BUF_LEN);
#if LOG_OUT_RX_LEN_INFO
        LOGI("USART3 RX %d byte.\r\n", Size);
#endif
    }
#endif

#if UART4_EN
    if (huart->Instance == UART4 && huart->RxState == HAL_UART_STATE_READY)
    {
        xStreamBufferSendFromISR(uart4_stream_buff, uart4_dma_rx_buff, Size, &xHigherPriorityTaskWoken);
        HAL_UARTEx_ReceiveToIdle_DMA(&huart4, uart4_dma_rx_buff, UART4_DMA_RX_BUF_LEN);
    }
#endif

#if UART6_EN
    if (huart->Instance == USART6 && huart->RxState == HAL_UART_STATE_READY)
    {
        xStreamBufferSendFromISR(uart6_stream_buff, uart6_dma_rx_buff, Size, &xHigherPriorityTaskWoken);
        HAL_UARTEx_ReceiveToIdle_DMA(&huart6, uart6_dma_rx_buff, UART6_DMA_RX_BUF_LEN);
    }
#endif

#if LPUART1_EN
    else if (huart->Instance == LPUART1 && huart->RxState == HAL_UART_STATE_READY)
    {
        xStreamBufferSendFromISR(lpuart1_stream_buff, lpuart1_dma_rx_buff, Size, &xHigherPriorityTaskWoken);
        HAL_UARTEx_ReceiveToIdle_DMA(&hlpuart1, lpuart1_dma_rx_buff, LPUART1_DMA_RX_BUF_LEN);
    }
#endif
    portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}


void stm32_uart_idle_handler(UART_HandleTypeDef *huart)
{
    uint32_t cndtr = 0;
    uint32_t reclenth = 0;
    uint8_t  *p_rx_dma_buff;
    uint16_t rx_buff_len = 0;
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;

    if((__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == RESET))
    {
        return;
    }

    __HAL_UART_CLEAR_IDLEFLAG(huart);
    HAL_UART_AbortReceive(huart);
//    cndtr = huart->hdmarx->Instance->CNDTR;


    if(huart->Instance == USART1)
    {
        reclenth = UART1_DMA_RX_BUF_LEN - cndtr; //;

        if (reclenth>0)
        {
            xStreamBufferSendFromISR(uart1_stream_buff, uart1_dma_rx_buff, reclenth, &xHigherPriorityTaskWoken);

        }

        rx_buff_len = UART1_DMA_RX_BUF_LEN;
        p_rx_dma_buff = uart1_dma_rx_buff;
    }
#if UART2_EN
    if(huart->Instance == USART2)
    {
//        xStreamBufferSendFromISR(uart2_stream_buff, uart2_dma_rx_buff, reclenth, 0);
        reclenth = UART2_DMA_RX_BUF_LEN - cndtr; //;
        if (reclenth>0)
        {
            xStreamBufferSendFromISR(uart2_stream_buff, uart2_dma_rx_buff, reclenth, &xHigherPriorityTaskWoken);
            LOGW("UART2 REV %d byte.\r\n", reclenth);
        }

        rx_buff_len = UART2_DMA_RX_BUF_LEN;
        p_rx_dma_buff = uart2_dma_rx_buff;
    }
#endif


#if UART3_EN
    if(huart->Instance == USART3)
    {
//        xStreamBufferSendFromISR(uart3_stream_buff, uart3_dma_rx_buff, reclenth, 0);
        reclenth = UART3_DMA_RX_BUF_LEN - cndtr; //;
        if (reclenth>0)
        {
            xStreamBufferSendFromISR(uart3_stream_buff, uart3_dma_rx_buff, reclenth, &xHigherPriorityTaskWoken);

        }

        rx_buff_len = UART3_DMA_RX_BUF_LEN;
        p_rx_dma_buff = uart3_dma_rx_buff;
    }
#endif

#if UART4_EN
    if(huart->Instance == UART4)
    {
        reclenth = UART4_DMA_RX_BUF_LEN - cndtr; //;
        if (reclenth>0)
        {
            xStreamBufferSendFromISR(uart4_stream_buff, uart4_dma_rx_buff, reclenth, 0);
        }


        rx_buff_len = UART4_DMA_RX_BUF_LEN;
        p_rx_dma_buff = uart4_dma_rx_buff;
    }

#endif
    HAL_UART_Receive_DMA(huart,p_rx_dma_buff, rx_buff_len);     //启动DMA接收
    __HAL_UART_ENABLE_IT(huart, UART_IT_IDLE);                  //开启空闲中断
    portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}

